% ---------------------------------------------------
% @doc 工作分配处理器.
% ---------------------------------------------------
-module(role_handler).
-include("cloap_record.hrl").

-export([init/2]).
-export([
         allowed_methods/2,
         content_types_provided/2, content_types_accepted/2,
         resource_exists/2, event/2
]).

init(Req, Opts) ->
    {cowboy_rest, Req, Opts}.


allowed_methods(Req, State) ->
    {
      [<<"GET">>, <<"POST">>, <<"HEAD">>, <<"OPTIONS">>],
      Req, State
    }.


content_types_provided(Req, State) ->
    Req1 = cowboy_req:set_resp_header(<<"access-control-allow-methods">>, <<"GET, POST, OPTIONS">>, Req),
    Req2 = cowboy_req:set_resp_header(<<"access-control-allow-origin">>, <<"*">>, Req1),
    {
      [
       {<<"application/json">>, event}
      ], Req2, State}.


content_types_accepted(Req, State) ->
    {[
      {<<"text/plain;charset=UTF-8">>, event},
      {<<"application/json">>, event}
     ],
     Req, State}.



resource_exists(Req, State) ->
  {true, Req, State}.



%% @doc 操作判断
event(Req, State) ->

    Dim    = cowboy_req:binding(dim,    Req),
    Id     = cowboy_req:binding(id,     Req),
    Action = cowboy_req:binding(action, Req),
    Method = cowboy_req:method(Req),


    case Method of
        <<"GET">> -> {jsx:encode(handle(Method, Dim, Id, Action, Req, State)), Req, State};
        <<"POST">> ->
            {ok, Body, _} = cowboy_req:body(Req),
            Params = jsx:decode(Body),
            Value = handle(Method, Dim, Id, Action, Params, State),
            Req1 = cowboy_req:set_resp_body(jsx:encode(Value), Req),
            {true, Req1, State}
    end.


%% --------------------------------------------------------------------------------
%% 组织分类
%% --------------------------------------------------------------------------------

handle(<<"GET">>, <<"rating">>, <<"all">>, undefined, _Req, _State) ->
    Result = cloap_handler:handle("rating.index", []),
    Organs = hash(organ),
    Positions = hash(position),
    Result1 = lists:map(fun(X) -> convert_member(Organs, X, groups) end, Result),
    Result2 = lists:map(fun(X1) -> convert_member(Positions, X1, positions) end, Result1),
    Result2;
handle(<<"POST">>, <<"rating">>, undefined, undefined, Params, _State) ->
    cloap_handler:handle("rating.create", Params);


%% --------------------------------------------------------------------------------
%% 岗位
%% --------------------------------------------------------------------------------
handle(<<"GET">>, <<"position">>, <<"all">>, undefined, _Req, _State) ->
    cloap_handler:handle("position.index", []);
handle(<<"POST">>, <<"position">>, undefined, undefined, Params, _State) ->
    cloap_handler:handle("position.create", Params);

%% --------------------------------------------------------------------------------
%% 机构
%% --------------------------------------------------------------------------------
handle(<<"GET">>, <<"organ">>, <<"all">>, undefined, _Req, _State) ->
    Result = cloap_handler:handle("organ.index", []),
    Users = hash(user),
    lists:map(fun(X) -> convert_member(Users, X, member) end, Result);
handle(<<"POST">>, <<"organ">>, undefined, undefined, Params, _State) ->
    cloap_handler:handle("organ.create", Params);




handle(<<"GET">>, <<"job">>, <<"all">>, undefined, _Req, _State) ->
    Users = hash(user),
    Positions = hash(position),
    Organs = hash(organ),
    Result = cloap_handler:handle("job.index", []),
    lists:map(
      fun(X) ->
              Organ = proplists:get_value(organ, X),
              Position = proplists:get_value(subject, X),
              replace_key(organ, proplists:get_value(Organ, Organs),
                          replace_key(subject, proplists:get_value(Position, Positions),
                                      convert_member(Users, X, assign)))
      end,
      Result);
handle(<<"POST">>, <<"job">>, undefined, undefined, Params, _State) ->
    cloap_handler:handle("job.create", Params);

%% --------------------------------------------------------------------------------
%% 用户
%% --------------------------------------------------------------------------------
handle(<<"GET">>, <<"user">>, <<"all">>, undefined, _Req, _State) ->
    cloap_handler:handle("user.index", []);
handle(<<"POST">>, <<"user">>, undefined, undefined, Params, _State) ->
    cloap_handler:handle("user.create", Params);


handle(<<"GET">>, <<"user">>, Id, undefined, _Req, _State) ->
    User = user_store:find_one(Id),
    #{dn := Dn} = User,
    Jobs = [R || R <-cloap_handler:handle("job.index", []), lists:member(Dn, proplists:get_value(assign, R, []))],
    User#{jobs => Jobs}.



hash(organ) ->
    lists:map(
      fun(X) ->
              Dn = proplists:get_value(dn, X),
              {Dn, X}
      end,
      cloap_handler:handle("organ.index", []));
hash(user) ->
    lists:map(
      fun(X) ->
              #{dn := Dn} = X,
              {Dn, X}
      end,
      cloap_handler:handle("user.index", []));
hash(position) ->
    lists:map(
      fun(X) ->
              Dn = proplists:get_value(dn, X),
              {Dn, X}
      end,
      cloap_handler:handle("position.index", [])).


convert_member(Hash, Node, Key) ->
    Members = [ proplists:get_value(R, Hash) || R <- proplists:get_value(Key, Node, []),
                                                 proplists:get_value(R, Hash) =/= undefined ],
    replace_key(Key, Members, Node).
replace_key(Key, Value, List) ->
    [{Key, Value} | proplists:delete(Key, List)].
